package org.tau.workshop2011.widgets

import java.awt.Dimension;
import javax.swing.JSplitPane;
import javax.swing.SpringLayout;

/**
* A smart enumeration for specifying the orientation of the MultiSplitPane.
* In addition for just having enumeration values, it has functions for
* returning layout constraints matching the orientation, modifying only the
* size of a Dimension that matches the orientation, etc.
*/
sealed class Orientation(start: String, center: String, end: String, jsSplitDirection: Int) {

  /**
   * The SpringLayout location modifiers for the begining, center and end
   * along this orientation
   */
  val springLayoutStart: String = start
  val springLayoutEnd: String = end
  val springLayoutCenter: String = center
  /**
   * The value needed for creating a JSplitPane that split's along this
   * axis
   */
  val jSplitPaneDirection: Int = jsSplitDirection;

  /**
   * Return the orientation which is not the current orientation
   */
  def other: Orientation = {
    this match {
      case Orientation.HORIZONTAL => Orientation.VERTICAL
      case Orientation.VERTICAL => Orientation.HORIZONTAL
      case _ => throw new AssertionError()
    }
  }

  /**
   * Let's have two Dimension objects which both represent a rectangle.
   * This function returns the size of the bounding rectangle that would
   * have been made if these two Dimensions where concatenated along this
   * orientation
   * @param dst The result will be saved into here
   */
  def concatAlongMe(dst: Dimension, add: Dimension) {
      setSize(dst, getSize(dst) + getSize(add));
      other.setSize(dst, math.max(other.getSize(dst), other.getSize(add)));
  }
  
  def copyConcatAlongMe(dst: Dimension, add: Dimension): Dimension = {
      val result = new Dimension(dst)
      concatAlongMe(result, add)
      result
  }

  /**
   * Get the size of a Dimension object along this orientation
   */
  def getSize(dim: Dimension): Int = {
    this match {
      case Orientation.HORIZONTAL => dim.width
      case Orientation.VERTICAL => dim.height
      case _ => throw new AssertionError()
    }
  }

  /**
   * Set the size of a Dimension object along this orientation
   */
  def setSize(dim: Dimension, value: Int) {
    this match {
      case Orientation.HORIZONTAL => dim.width = value
      case Orientation.VERTICAL => dim.height = value
      case _ => throw new AssertionError()
    }
  }
}


object Orientation {
  val HORIZONTAL: Orientation = new Orientation(SpringLayout.WEST, SpringLayout.HORIZONTAL_CENTER, SpringLayout.EAST, JSplitPane.HORIZONTAL_SPLIT)
  val VERTICAL: Orientation = new Orientation(SpringLayout.NORTH, SpringLayout.VERTICAL_CENTER, SpringLayout.SOUTH, JSplitPane.VERTICAL_SPLIT)
}

